/*
*********************************************************************************************************
*                                     MICIRUM BOARD SUPPORT PACKAGE
*
*                          (c) Copyright 2003-2006; Micrium, Inc.; Weston, FL
*
*               All rights reserved.  Protected by international copyright laws.
*               Knowledge of the source code may NOT be used to develop a similar product.
*               Please help us continue to provide the Embedded community with the finest
*               software available.  Your honesty is greatly appreciated.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*
*                                        BOARD SUPPORT PACKAGE
*
*                                              NXP LPC2148
*                                                on the
*                                       IAR LPC2148 Kickstart Card
*
* Filename      : bsp.c
* Version       : V1.01
* Programmer(s) : JJL
*               : FT
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/

#define  BSP_GLOBALS
#include <includes.h>


/*
*********************************************************************************************************
*                                            LOCAL DEFINES
*********************************************************************************************************
*/

#define  LED_1_BIT                           (CPU_INT32U)(1 << 25)

#define  LCD_BIT_RW                          (CPU_INT32U)(1 << 29)
#define  LCD_BIT_E                           (CPU_INT32U)(1 << 28)
#define  LCD_BIT_RS                          (CPU_INT32U)(1 << 22)
#define  LCD_BIT_DATA3                       (CPU_INT32U)(1 << 13)
#define  LCD_BIT_DATA2                       (CPU_INT32U)(1 << 12)
#define  LCD_BIT_DATA1                       (CPU_INT32U)(1 << 11)
#define  LCD_BIT_DATA0                       (CPU_INT32U)(1 << 10)


/*
*********************************************************************************************************
*                                           LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                          LOCAL DATA TYPES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                            LOCAL TABLES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                       LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

        CPU_INT32U  VIC_SpuriousInt;


/*
*********************************************************************************************************
*                                      LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/

static  void  BSP_ADC_Init          (void);
static  void  BSP_LED_Init         (void);

static  void  BSP_PLL_Init         (void);
static  void  BSP_IO_Init          (void);
static  void  BSP_MAM_Init         (void);

#ifdef DISP_MODULE_PRESENT
static  void  DispE_High           (void);
static  void  DispE_Low            (void);
static  void  DispRW_High          (void);
static  void  DispRW_Low           (void);

static  void  BSP_Tmr1_Init        (void);
static  void  BSP_Tmr1_Dly         (CPU_INT32U dly);
#endif

static  void  BSP_Tmr_TickInit     (void);

static  void  BSP_VIC_Init         (void);
static  void  BSP_VIC_Dummy        (void);
static  void  BSP_VIC_DummyWDT     (void);
static  void  BSP_VIC_DummyTIMER0  (void);
static  void  BSP_VIC_DummyTIMER1  (void);
static  void  BSP_VIC_DummyUART0   (void);
static  void  BSP_VIC_DummyUART1   (void);
static  void  BSP_VIC_DummyPWM0    (void);
static  void  BSP_VIC_DummyI2C     (void);
static  void  BSP_VIC_DummySPI     (void);
static  void  BSP_VIC_DummyRTC     (void);
static  void  BSP_VIC_DummyEINT0   (void);
static  void  BSP_VIC_DummyEINT1   (void);
static  void  BSP_VIC_DummyEINT2   (void);

/*
*********************************************************************************************************
*                                     LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*********************************************************************************************************
**                                         GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             BSP_Init()
*
* Description : Initialize the Board Support Package (BSP).
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Note(s)     : (1) This function SHOULD be called before any other BSP function is called.
*********************************************************************************************************
*/

void  BSP_Init (void)
{
    MEMMAP  = 1;         

    BSP_PLL_Init();                                             /* Initialize PLL0 and the VPB Divider Register             */
    BSP_MAM_Init();                                             /* Initialize the Memory Acceleration Module                */
    BSP_VIC_Init();                                             /* Initialize the Vectored Interrupt Controller             */
    
    
    //BSP_IO_Init();                                              /* Initialize the board's I/Os                              */
    //BSP_LED_Init();                                             /* Initialize the LED controls                              */
    //BSP_ADC_Init();                                             /* Intiialize the ADC control                               */

    BSP_Tmr_TickInit();                                         /* Initialize the uC/OS-II tick interrupt                   */

#ifdef DISP_MODULE_PRESENT
    BSP_Tmr1_Init();
#endif
}


/*
*********************************************************************************************************
*                                            BSP_CPU_ClkFreq()
*
* Description : Get the CPU clock frequency.
*
* Argument(s) : none.
*
* Return(s)   : The CPU clock frequency, in Hz.
*********************************************************************************************************
*/

CPU_INT32U  BSP_CPU_ClkFreq (void)
{
    CPU_INT32U  msel;
    CPU_INT32U  cpu_clk_freq;


    msel         = (CPU_INT32U)(PLLCFG & 0x1F);
    cpu_clk_freq = BSP_MAIN_OSC_FREQ * (msel + 1);
    return (cpu_clk_freq);
}


/*
*********************************************************************************************************
*                                            BSP_CPU_PclkFreq()
*
* Description : Get the peripheral clock frequency.
*
* Argument(s) : none.
*
* Return(s)   : The peripheral clock frequency, in Hz.
*********************************************************************************************************
*/

CPU_INT32U  BSP_CPU_PclkFreq (void)
{
    CPU_INT32U  msel;
    CPU_INT32U  vpbdiv;
    CPU_INT32U  clk_freq;
    CPU_INT32U  pclk_freq;

    msel         = (CPU_INT32U)(PLLCFG   & 0x1F);
    clk_freq     = BSP_MAIN_OSC_FREQ * (msel + 1);

    vpbdiv       = (CPU_INT32U)(VPBDIV & 0x03);
    switch (vpbdiv) {
        case 0:
             pclk_freq = clk_freq / 4;
             break;

        case 1:
             pclk_freq = clk_freq;
             break;

        case 2:
             pclk_freq = clk_freq / 2;
             break;

        default:
             pclk_freq = clk_freq / 4;
             break;
    }
    return (pclk_freq);
}


/*
*********************************************************************************************************
*                                          OS_CPU_ExceptHndlr()
*
* Description : Handle any exceptions.
*
* Argument(s) : except_id     ARM exception type:
*
*                                  OS_CPU_ARM_EXCEPT_RESET             0x00
*                                  OS_CPU_ARM_EXCEPT_UNDEF_INSTR       0x01
*                                  OS_CPU_ARM_EXCEPT_SWI               0x02
*                                  OS_CPU_ARM_EXCEPT_PREFETCH_ABORT    0x03
*                                  OS_CPU_ARM_EXCEPT_DATA_ABORT        0x04
*                                  OS_CPU_ARM_EXCEPT_ADDR_ABORT        0x05
*                                  OS_CPU_ARM_EXCEPT_IRQ               0x06
*                                  OS_CPU_ARM_EXCEPT_FIQ               0x07
*
* Return(s)   : none.
*
* Caller(s)   : OS_CPU_ARM_EXCEPT_HANDLER(), which is declared in os_cpu_a.s.
*********************************************************************************************************
*/

void  OS_CPU_ExceptHndlr (CPU_INT32U  except_id)
{
    CPU_FNCT_VOID  pfnct;


    if (except_id == OS_CPU_ARM_EXCEPT_IRQ) {

        pfnct = (CPU_FNCT_VOID)VICVectAddr;                     /* Read the interrupt vector from the VIC                   */
        while (pfnct != (CPU_FNCT_VOID)0) {                     /* Make sure we don't have a NULL pointer                   */
          (*pfnct)();                                           /* Execute the ISR for the interrupting device              */
            VICVectAddr = 1;                                    /* Acknowlege the VIC interrupt                             */
            pfnct = (CPU_FNCT_VOID)VICVectAddr;                 /* Read the interrupt vector from the VIC                   */
        }

    } else {

                                                                /* Infinite loop on other exceptions.                       */
                                                                /* Should be replaced by other behavior (reboot, etc.)      */
        while (DEF_TRUE) {
            ;
        }
    }
}


/*
*********************************************************************************************************
*                                           BSP_IntDisAll()
*
* Description : Disable ALL interrupts.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_IntDisAll (void)
{
    VICIntEnClear = 0xFFFFFFFFL;                                /* Disable ALL interrupts                                   */
}


/*
*********************************************************************************************************
*********************************************************************************************************
**                                          uC/LCD FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                            DispInitPort()
*
* Description : Initializes the I/O ports used by the display driver.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Note(s)     : (1) The I/Os for the LCD module are initialized in BSP_IO_Init().
*********************************************************************************************************
*/

#ifdef DISP_MODULE_PRESENT
void  DispInitPort (void)
{
    ;
}
#endif


/*
*********************************************************************************************************
*                                              DispDataWr()
*
* Description : Sends a single byte to the display device.
*
* Argument(s) : 'data'      Data to send to the display device
*
* Return(s)   : none.
*
* Note(s)     : (1) The LPC2148 evaluation board uses a 4 bit interface.
*                   If an 8 bit interface is used. BSP_IO_Init() and DispDataWr() will need
*                   to be modified to reflect the new databus. In 8 bit mode, DispDataWrOneNibble()
*                   is not necessary.
*********************************************************************************************************
*/

#ifdef DISP_MODULE_PRESENT
void  DispDataWr (CPU_INT08U data)
{
    CPU_INT32U  value;


    DispRW_Low();                                               /* Set R/W write LOW to write to the LCD module             */

    DispE_High();                                               /* Write the UPPER nibble to the LCD module                 */
    value  =  ((data >> 4) & 0x0F) << 10;

    FIO0SET = value;
    value  = (~(data >> 4) & 0x0F) << 10;
    FIO0CLR = value;

    DispDly_uS(100);
    DispE_Low();

    DispDly_uS(100);                                            /* Write the LOWER nibble to the LCD module                 */
    DispE_High();
    value  =  (data & 0x0F) << 10;

    FIO0SET = value;
    value  = (~data & 0x0F) << 10;
    FIO0CLR = value;

    DispDly_uS(100);
    DispE_Low();
}

#if DISP_BUS_WIDTH == 4
void DispDataWrOneNibble(CPU_INT08U data)
{
    CPU_INT32U  value;


    DispRW_Low();                                               /* Set R/W write LOW to write to the LCD module             */

    DispE_High();                                               /* Write the UPPER nibble to the LCD module                 */
    value  =  ((data >> 4) & 0x0F) << 10;

    FIO0SET = value;
    value  = (~(data >> 4) & 0x0F) << 10;
    FIO0CLR = value;

    DispDly_uS(100);
    DispE_Low();
}
#endif

#endif


/*
*********************************************************************************************************
*                                               DispDly_uS()
*
* Description : Delay for the specified number of microseconds.
*
* Argument(s) : us      Number of microseconds
*
* Return(s)   : none.
*********************************************************************************************************
*/

#ifdef DISP_MODULE_PRESENT
void  DispDly_uS (CPU_INT32U us)
{
    BSP_Tmr1_Dly(us);
}
#endif


/*
*********************************************************************************************************
*                                            DispSel()
*
* Description : Change the Register Select control line to the LCD controller to select either
*               command or data register.
*
* Argument(s) : sel         Indicates whether command or data register should be selected:
*                           DISP_SEL_CMD_REG    select command register
*                           DISP_SEL_DATA_REG   select data    register
*
* Return(s)   : none.
*********************************************************************************************************
*/

#ifdef DISP_MODULE_PRESENT
void  DispSel (CPU_INT08U sel)
{
    if (sel == DISP_SEL_CMD_REG) {
        FIO0CLR = LCD_BIT_RS;                                   /* Select the command register (RS low)                     */
    } else {
        FIO0SET = LCD_BIT_RS;                                   /* Select the data    register (RS high)                    */
    }
}
#endif


/*
*********************************************************************************************************
*                                      DISPLAY CONTROL LINE FUNCTIONS
*********************************************************************************************************
*/

#ifdef DISP_MODULE_PRESENT
static  void  DispE_High (void)
{
    FIO0SET = LCD_BIT_E;
}


static  void  DispE_Low (void)
{
    FIO0CLR = LCD_BIT_E;
}


static  void  DispRW_High (void)
{
    FIO0SET = LCD_BIT_RW;
}


static  void  DispRW_Low (void)
{
    FIO0CLR = LCD_BIT_RW;
}
#endif


/*
*********************************************************************************************************
*                                        BSP_Tmr1_Init()
*
* Description : Intializes the Timer 1
*
* Argument(s) : none
*
* Return(s)   : none.
*********************************************************************************************************
*/


#ifdef DISP_MODULE_PRESENT
static  void  BSP_Tmr1_Init (void)
{
    T1PR  = 0;
    T1TCR = 0x00000001;                                         /* Enable the timer                                         */
}
#endif

/*
*********************************************************************************************************
*                                        BSP_Tmr1_Dly()
*
* Description : Uses the second timer to produce a short delay
*
* Argument(s) : dly         The number of microseconds for which to delay
*
* Return(s)   : none.
*********************************************************************************************************
*/
#ifdef DISP_MODULE_PRESENT
static  void  BSP_Tmr1_Dly (CPU_INT32U dly)
{
    CPU_INT32U  original_val;
    CPU_INT32U  current_val;
    CPU_INT32U  dly_cycles;
    CPU_INT32U  mult;


    original_val = T1TC;
    mult         = (BSP_CPU_PclkFreq()) / 1000000;
    dly_cycles   = mult * dly;
    current_val  = T1TC;
    while ((current_val - original_val) < dly_cycles) {
        current_val = T1TC;
    }
}
#endif


/*
*********************************************************************************************************
*********************************************************************************************************
**                                       PB, LED, AND ADC FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             BSP_LED_Init()
*
* Description : Setup the I/O for the LEDs.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_LED_Init (void)
{
    BSP_LED_Off(0);                                            /* Turn OFF all the LEDs                                    */
}


/*
*********************************************************************************************************
*                                             BSP_LED_On()
*
* Description : Turn ON any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    turn ON all LEDs on the board
*                       1    turn ON LCD backlight
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_LED_On (CPU_INT08U led)
{
    switch (led) {
        case 0:
        case 1:
             FIO0SET = LED_1_BIT;
             break;
        default:
             break;
    }
}


/*
*********************************************************************************************************
*                                             BSP_LED_Off()
*
* Description : Turn OFF any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    turn OFF all LEDs on the board
*                       1    turn OFF LCD backlight
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_LED_Off (CPU_INT08U led)
{
    switch (led) {
        case 0:
        case 1:
             FIO0CLR = LED_1_BIT;
             break;
        default:
             break;
    }
}


/*
*********************************************************************************************************
*                                             BSP_LED_Toggle()
*
* Description : TOGGLE any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    TOGGLE all LEDs on the board
*                       1    TOGGLE LCD backlight
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_LED_Toggle (CPU_INT08U led)
{
    CPU_INT32U  are_off;
    CPU_INT32U  are_on;


    switch (led) {
        case 0:
        case 1:
             are_off    =  FIO0PIN ^ LED_1_BIT;
             are_on     = ~FIO0PIN ^ LED_1_BIT;
             FIO0CLR    =  are_on;
             FIO0SET    =  are_off;
             break;
    }
}


/*
*********************************************************************************************************
*                                         BSP_PB_GetStatus()
*
* Description : Get the status of a push button on the board.
*
* Argument(s) : pb      The ID of the push button to probe
*
*                       1    probe the push button B1
*                       2    probe the push button B2
*
* Return(s)   : DEF_FALSE   if the push button is pressed
*               DEF_TRUE    if the push button is not pressed
*********************************************************************************************************
*/

CPU_BOOLEAN  BSP_PB_GetStatus (CPU_INT08U pb)
{
    CPU_BOOLEAN  status;


    status = DEF_FALSE;

    switch (pb) {
        case 1:
             if ((FIO0PIN & (1 << 15)) == 0) {
                 return (DEF_TRUE);
             }
             break;

        case 2:
             if ((FIO0PIN & (1 << 16)) == 0) {
                 return (DEF_TRUE);
             }
             break;

        default:
             break;
    }

    return (status);
}

/*
*********************************************************************************************************
*                                         BSP_ADC_Init()
*
* Description : Initializes the board's ADC.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

static  void  BSP_ADC_Init (void)
{
    CPU_INT08U  div;


    div      = (BSP_CPU_PclkFreq() / 4500000) + 1;
                                                                /* Configure ADC ...                                        */
    AD0CR    = (0x08 <<  0)                                     /*  ... Sample/convert pin AD0.3 ...                        */
             | (div  <<  8)                                     /*  ... Set divider so sample freq. < 4.5 MHz ...           */
             | (   1 << 16)                                     /*  ... Use burst mode for continuous conversion ...        */
             | (0x00 << 17)                                     /*  ... Use 11 clocks per conversion for 10-bit accuracy ...*/
             | (   1 << 21);                                    /*  ... Power up the ADC.                                   */

                                                                /* Select AD0.3 function for PIN0.30                        */
    PINSEL1 |=  (1 << 28);
    PINSEL1 &= ~(1 << 29);

    AD0CR   |=  (0x01 << 24);                                   /* Start conversion                                         */
}


/*
*********************************************************************************************************
*                                           BSP_ADC_GetStatus()
*
* Description : This function initializes the board's ADC
*
* Argument(s) : adc     The ID of the ADC to probe:
*                       1   Probe the potentiometer.
*
* Return(s)   : The numerator of the binary fraction representing the result of the latest ADC conversion.
*               This value will be a 10-bit value between 0x0000 and 0x03FF, inclusive.
*********************************************************************************************************
*/

CPU_INT16U  BSP_ADC_GetStatus (CPU_INT08U  adc)
{
    if (adc == 1) {
        return ((AD0DR3 >> 6) & 0x03FF);
    } else {
        return (0);
    }
}


/*
*********************************************************************************************************
*                              BSP_PB_EINT0_Init() / BSP_PB_EINT2_Init()
*
* Description : Configure external interrupt to respond to change in the push buttons.  An
*               interrupt will be generated on a rising edge.
*
* Argument(s) : isr         ISR which will receive the interrupt.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_PB_EINT0_Init (CPU_FNCT_VOID isr)
{
    EXTINT_bit.EINT0        = 1;

    VICIntSelect           &= ~(1 << VIC_EINT0);                /* Enable interrupts                                        */
    VICVectAddr3            = (CPU_INT32U)isr;                  /* Set the vector address                                   */
    VICVectCntl3            = 0x20 | VIC_EINT0;                 /* Enable vectored interrupts                               */
    VICIntEnable            = (1 << VIC_EINT0);                 /* Enable Interrupts                                        */

    EXTMODE_bit.EXTMODE0    = 1;
    EXTPOLAR_bit.EXTPOLAR0  = 0;
}

void  BSP_PB_EINT2_Init (CPU_FNCT_VOID isr)
{
    EXTINT_bit.EINT2        = 1;

    VICIntSelect           &= ~(1 << VIC_EINT2);                /* Enable interrupts                                        */
    VICVectAddr5            = (CPU_INT32U)isr;                  /* Set the vector address                                   */
    VICVectCntl5            = 0x20 | VIC_EINT2;                 /* Enable vectored interrupts                               */
    VICIntEnable            = (1 << VIC_EINT2);                 /* Enable Interrupts                                        */

    EXTMODE_bit.EXTMODE2    = 1;
    EXTPOLAR_bit.EXTPOLAR2  = 0;
}


/*
*********************************************************************************************************
*                                      BSP_ADC_EINT3_Init()
*
* Description : Configure external interrupt to respond to change in the ADC.
*
* Argument(s) : isr         ISR which will receive the interrupt.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_ADC_EINT3_Init (CPU_FNCT_VOID isr)
{
    EXTINT_bit.EINT3        = 1;

    VICIntSelect           &= ~(1 << VIC_EINT3);                /* Enable interrupts                                        */
    VICVectAddr4            = (CPU_INT32U)isr;                  /* Set the vector address                                   */
    VICVectCntl4            = 0x20 | VIC_EINT3;                 /* Enable vectored interrupts                               */
    VICIntEnable            = (1 << VIC_EINT3);                 /* Enable Interrupts                                        */

    EXTMODE_bit.EXTMODE3    = 1;
    EXTPOLAR_bit.EXTPOLAR3  = 0;
}


/*
*********************************************************************************************************
*********************************************************************************************************
*                             uC/Probe PLUG-IN FOR uC/OS-II FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                       OSProbe_TmrInit()
*
* Description : Select & initialize a timer for use with the uC/Probe Plug-In for uC/OS-II.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

#if (APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && (OS_PROBE_HOOKS_EN == 1)
void  OSProbe_TmrInit (void)
{
    T1PR  = 0;
    T1TCR = 0x00000001;                                         /* Enable the timer                                         */

}
#endif


/*
*********************************************************************************************************
*                                        OSProbe_TmrRd()
*
* Description : Read the current counts of a 32-bit free running timer.
*
* Argument(s) : none.
*
* Return(s)   : The 32bit counts of the timer.
*********************************************************************************************************
*/

#if (APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && (OS_PROBE_HOOKS_EN == 1)
CPU_INT32U  OSProbe_TmrRd (void)
{
    return ((CPU_INT32U)T1TC);
}
#endif

/*
*********************************************************************************************************
*********************************************************************************************************
**                                     uC/OS-II TIMER FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                            BSP_Tmr_TickInit()
*
* Description : Initialize uC/OS-II's tick source.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

static  void  BSP_Tmr_TickInit (void)
{
    CPU_INT32U  pclk_freq;
    CPU_INT32U  tmr_reload;

                                                                /* VIC TIMER #0 Initialization                              */
    VICIntSelect &= ~(1 << VIC_TIMER0);                         /* Enable interrupts                                        */
    VICVectAddr2  = (CPU_INT32U)BSP_Tmr_TickISR_Handler;        /* Set the vector address                                   */
    VICVectCntl2  = 0x20 | VIC_TIMER0;                          /* Enable vectored interrupts                               */
    VICIntEnable  = (1 << VIC_TIMER0);                          /* Enable Interrupts                                        */

    pclk_freq     = BSP_CPU_PclkFreq();
    tmr_reload    = pclk_freq / OS_TICKS_PER_SEC;
    T0TCR         = 0;                                          /* Disable timer 0.                                         */
    T0PC          = 0;                                          /* Prescaler is set to no division.                         */

    T0MR0         = tmr_reload;
    T0MCR         = 3;                                          /* Interrupt on MR0 (reset TC)                              */

    T0CCR         = 0;                                          /* Capture is disabled.                                     */
    T0EMR         = 0;                                          /* No external match output.                                */
    T0TCR         = 1;                                          /* Enable timer 0                                           */
}


/*
*********************************************************************************************************
*                                       BSP_Tmr_TickISR_Handler()
*
* Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  BSP_Tmr_TickISR_Handler (void)
{
    T0TCR &= ~DEF_BIT_00;
    T0TC   = 0;
    T0IR   = DEF_BIT_00;                                         /* Clear timer #0 interrupt                                 */
    T0TCR |= DEF_BIT_00;

    OSTimeTick();                                                /* Call uC/OS-II's OSTimeTick()                             */
}


/*
*********************************************************************************************************
*********************************************************************************************************
**                                          LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                        BSP_PLL_Init()
*
* Description : Set up and activate the PLL
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

static  void  BSP_PLL_Init (void)
{
#if OS_CRITICAL_METHOD == 3                                     /* Allocate storage for CPU status register                 */
    OS_CPU_SR   cpu_sr = 0;
#endif
    CPU_INT16U  loop_ctr;

                                                                /* Configure PLL0, which determines the CPU clock           */
    PLLCFG   = 0x00000023;                                      /* Use PLL values of M = 4 and P = 2                        */
    PLLCON  |= 0x00000001;                                      /* Set the PLL Enable bit                                   */

    OS_ENTER_CRITICAL();
    PLLFEED  = 0xAA;                                            /* Write to the PLL Feed register                           */
    PLLFEED  = 0x55;
    OS_EXIT_CRITICAL();

    loop_ctr = 10000;                                           /* Wait for the PLL to lock into the new frequency          */
    while (((PLLSTAT & DEF_BIT_10) == 0) && (loop_ctr > 0)) {
        loop_ctr--;
    }

    PLLCON  |= 0x00000002;                                      /* Connect the PLL                                          */

    OS_ENTER_CRITICAL();
    PLLFEED  = 0xAA;                                            /* Write to the PLL Feed register                           */
    PLLFEED  = 0x55;
    OS_EXIT_CRITICAL();

    VPBDIV   = 0x00000002;                                      /* Set the VPB frequency to one-half of the CPU clock       */
}


/*
*********************************************************************************************************
*                                          BSP_IO_Init()
*
* Description : Initilize the GPIO pins.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Note(s)     :  (1) The pins P1.36-26 are setup as a Debug port and the pins P1.25-16 are setup as a
*                   trace port (by the last statements in this function).  If pins for one of these
*                   are to be used as GPIO, comment out the appropriate statement.
*
*               (2) Additional hardware may be necessary for using the Trace or Debug capability.
*                   According to section 23.5 of the LPC2148 user manual (UM10139, rev. 02):
*
*                       "To have these pins [P1.25-16] come as a Trace port, connect a
*                        weak bias resistor (4.7 kOhm) between the P1.20/TRACESYNC pin and Vss."
*
*                   Similarly, according to section 22.5 of the LPC2148 user manual,
*
*                       "To have them [pins P1.36-26] come up as a Debug port, connect a weak
*                        bias resistor (4.7-10kOhm depending on the external JTAG circuitry)
*                        between Vss and the P1.26/RTCK pin"
*********************************************************************************************************
*/

static  void  BSP_IO_Init (void)
{
    CPU_INT32U  value;


    SCS      = 0x00000001;                                      /* Fast GPIO registers will be used                         */

    value    = (1 << 16) | (1 << 15);                           /* Push buttons B2 and B1                                   */
    FIO0DIR &= ~value;

                                                                /* LCD control lines                                        */
    value    = ~((3 << 20) | (3 << 22) | (3 << 24) | (3 << 26));
    PINSEL0 &= value;
                                                                /* LCD data    lines                                        */
    value    = ~((3 << 12) | (3 << 24) | (3 << 26));
    PINSEL1 &= value;
    value    = LCD_BIT_DATA3 | LCD_BIT_DATA2 | LCD_BIT_DATA1 | LCD_BIT_DATA0 | LCD_BIT_E | LCD_BIT_RS | LCD_BIT_RW | LED_1_BIT;

    FIO0DIR |= value;

#ifdef DISP_MODULE_PRESENT
    DispRW_High();
#endif

                                                                /* The following statements setup the Trace/Debug           */
                                                                /* capabilitiy. If the pins indicated are to be used as     */
                                                                /* GPIO, remove or comment out these statements.            */

    PINSEL2  |= 0x00000004;                                     /* The pins P1.36-26 will be used as a Debug port.          */
    PINSEL2  |= 0x00000008;                                     /* The pins P1.25-16 will be used as a Trace port.          */
}


/*
*********************************************************************************************************
*                                             BSP_MAM_Init()
*
* Description : Initialize the memory acceleration module.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

static  void  BSP_MAM_Init (void)
{
    MAMCR  = 0x00;                                              /* Disable the Memory Accelerator Module                    */
    MAMTIM = 0x03;                                              /* MAM fetch cycles are 3 CCLKs in duration                 */
    MAMCR  = 0x02;                                              /* Enable the Memory Accelerator Module                     */
}

/*
*********************************************************************************************************
*********************************************************************************************************
**                                            VIC FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                        Vectored Interrupt Controller
*********************************************************************************************************
*/

static  void  BSP_VIC_Init (void)
{
    VICIntEnClear = 0xFFFFFFFF;                                 /* Disable ALL interrupts                                   */
    VICProtection = 0;                                          /* Setup interrupt controller                               */

    VICVectAddr1  = (CPU_INT32U)BSP_VIC_DummyWDT;               /* Set the vector address                                   */
    VICVectAddr2  = (CPU_INT32U)BSP_VIC_DummyTIMER0;
    VICVectAddr3  = (CPU_INT32U)BSP_VIC_DummyTIMER1;
    VICVectAddr4  = (CPU_INT32U)BSP_VIC_DummyUART0;
    VICVectAddr5  = (CPU_INT32U)BSP_VIC_DummyUART1;
    VICVectAddr6  = (CPU_INT32U)BSP_VIC_DummyPWM0;
    VICVectAddr7  = (CPU_INT32U)BSP_VIC_DummyI2C;
    VICVectAddr8  = (CPU_INT32U)BSP_VIC_DummySPI;
    VICVectAddr9  = (CPU_INT32U)BSP_VIC_DummyRTC;
    VICVectAddr10 = (CPU_INT32U)BSP_VIC_DummyEINT0;
    VICVectAddr11 = (CPU_INT32U)BSP_VIC_DummyEINT1;
    VICVectAddr12 = (CPU_INT32U)BSP_VIC_DummyEINT2;
}

static  void  BSP_VIC_Dummy (void)
{
    while (1) {
        (void)VIC_SpuriousInt;
    }
}

static  void  BSP_VIC_DummyWDT (void)
{
    VIC_SpuriousInt = VIC_WDT;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyTIMER0 (void)
{
    VIC_SpuriousInt = VIC_TIMER0;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyTIMER1 (void)
{
    VIC_SpuriousInt = VIC_TIMER1;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyUART0 (void)
{
    VIC_SpuriousInt = VIC_UART0;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyUART1 (void)
{
    VIC_SpuriousInt = VIC_UART1;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyPWM0 (void)
{
    VIC_SpuriousInt = VIC_UART1;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyI2C (void)
{
    VIC_SpuriousInt = VIC_I2C;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummySPI (void)
{
    VIC_SpuriousInt = VIC_SPI;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyRTC (void)
{
    VIC_SpuriousInt = VIC_RTC;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyEINT0 (void)
{
    VIC_SpuriousInt = VIC_EINT0;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyEINT1 (void)
{
    VIC_SpuriousInt = VIC_EINT1;
    BSP_VIC_Dummy();
}

static  void  BSP_VIC_DummyEINT2 (void)
{
    VIC_SpuriousInt = VIC_EINT2;
    BSP_VIC_Dummy();
}

/*
*********************************************************************************************************
*********************************************************************************************************
**                                            SPI FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                        SPI_Init()
*
* Description : Initialize the SSP controller.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  SPI_Init (void)
{
#if (BSP_CFG_SPI == BSP_USE_SPI)                                /* SSP Controller                                           */
    CPU_INT32U  pin_status;
    CPU_INT32U  power_status;
    CPU_INT32U  io_dir;


    power_status  = PCONP;
    power_status |= 0x00000400;
    PCONP         = power_status;
                                                                /* SSEL is left as a GPIO pin                               */
    pin_status    = PINSEL1;
    pin_status   &= 0xFFFFFCAB;
    pin_status   |= 0x000000A8;
    PINSEL1       = pin_status;

    io_dir        = FIO0DIR;
    io_dir       |= 0x00100000;
    FIO0DIR       = io_dir;

    SSPCPSR       = 0x0000001E;                                 /* Use a clock rate of 400 kHz                              */
    SSPCR0        = 0x000001C7;                                 /* 8-bit data transfers will be used                        */
    SSPCR1        = 0x00000002;                                 /* Enable the SSP Controller                                */

#endif

#if (BSP_CFG_SPI == BSP_USE_GPIO)                               /* GPIO Pins using fast GPIO registers                      */

    CPU_INT32U  pin_status;
    CPU_INT32U  io_dir;


    pin_status    = PINSEL1;                                    /* Initialize the appropriate pins                          */
    pin_status   &= 0xFFFFFC03;
    PINSEL1       = pin_status;

    io_dir        = FIO0DIR;
    io_dir       |= 0x001A0000;
    io_dir       &= 0xFFFBFFFF;
    FIO0DIR       = io_dir;

#endif
}
